package com.njtoyo.taxi.admin.service.open.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.logic.business.simple_call.SimpleCallBackLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoArea;
import com.njtoyo.taxi.admin.mapper.master.entity.SimpleCallAreaMapping;
import com.njtoyo.taxi.admin.mapper.master.entity.SimpleCallBacklog;
import com.njtoyo.taxi.admin.mapper.master.enums.SimpleCallBacklogState;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoAreaMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.SimpleCallAreaMappingMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.SimpleCallBacklogMapper;
import com.njtoyo.taxi.admin.mapper.secondary.mapper.AdminUserMapper;
import com.njtoyo.taxi.admin.rest.wrapper.open.simple_call.CreateSimpleCallWrapper;
import com.njtoyo.taxi.admin.service.open.OpenSimpleCallService;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@DS(Const.PRIMARY_DS)
@Slf4j
public class OpenSimpleCallServiceImpl implements OpenSimpleCallService {

    @Autowired
    private SimpleCallBacklogMapper simpleCallBacklogMapper;

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    @Autowired
    private SimpleCallBackLogic simpleCallBackLogic;

    @Autowired
    private SimpleCallAreaMappingMapper simpleCallAreaMappingMapper;

    @Autowired
    private GeoAreaMapper geoAreaMapper;

    @Autowired
    private AdminUserMapper adminUserMapper;

    @Override
    public RestResult createBacklog(CreateSimpleCallWrapper wrapper) {
        SimpleCallAreaMapping areaMapping = simpleCallAreaMappingMapper.selectOne(new QueryWrapper<SimpleCallAreaMapping>().eq("callee_number", wrapper.getCalledNumber()));
        if (Objects.isNull(areaMapping)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        GeoArea area = geoAreaMapper.selectById(areaMapping.getAreaId());

        SimpleCallBacklog backlog = new SimpleCallBacklog();
        String audioUrl = "http://" + simpleCallDomain + "/" + wrapper.getAudioUrl();
        backlog.setMobileNumber(wrapper.getMobileNumber())
                .setMappingId(areaMapping.getId())
                .setAreaIds(areaMapping.getAreaIds())
                .setAdCode(area.getAdCode())
                .setAreaId(area.getId())
                .setAudioUrl(audioUrl)
                .setAudioUrlMd5(SecureUtil.md5(audioUrl))
                .setState(SimpleCallBacklogState.init);

        simpleCallBacklogMapper.insert(backlog);
        // 判断是否有在线用户
        List<Long> userIds = adminUserMapper.getPhoneOnlineAdminUserIds();
        log.info("当前在线客服为: {}", userIds);
        if (userIds.size() > 0) {
            // 判断是否自动发送
            if (areaMapping.getAutomaticSend().equals(Boolean.TRUE)) {
                if (areaMapping.getDelaySeconds() == 0) { // 表示立即发送
                    log.info("电召数据立即发单 {}", backlog.getId());
                    simpleCallBackLogic.sendSimpleCallBacklog(backlog.getId());
                } else {
                    DateTime dateTime = DateUtil.offsetSecond(new Date(), areaMapping.getDelaySeconds().intValue());
                    new LambdaUpdateChainWrapper<>(simpleCallBacklogMapper)
                            .eq(SimpleCallBacklog::getId, backlog.getId())
                            .set(SimpleCallBacklog::getSystemSendTimestamp, dateTime.getTime() / 1000)
                            .update();
                    log.info("电召数据 {}, 将于 {} 时自动发单", backlog.getId(), dateTime);
                    taskScheduler.schedule(() -> simpleCallBackLogic.sendSimpleCallBacklog(backlog.getId()), dateTime);
                }
            }
        } else {
            log.info("无客服在线，直接发单");
            simpleCallBackLogic.sendSimpleCallBacklog(backlog.getId());
        }

        return RestResult.success();
    }

    @Override
    public RestResult getUploadToken() {
        String token = getToken(simpleCallBucket);
        return RestResult.success().add("token", token).add("domain", simpleCallDomain);
    }

    @Value("${config.qiniu.accessKey}")
    private String accessKey;

    @Value("${config.qiniu.secretKey}")
    private String secretKey;

    @Value("${config.qiniu.buckets.simpleCall.bucket}")
    private String simpleCallBucket;

    @Value("${config.qiniu.buckets.simpleCall.domain}")
    private String simpleCallDomain;

    private String getToken(String bucket) {
        Auth auth = Auth.create(accessKey, secretKey);
        return auth.uploadToken(bucket);
    }
}
